package com.lemon.smartsafety.utils;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.lemon.smartsafety.R;
import com.lemon.smartsafety.app.IApplication;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.UsingFreqLimitedMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.nostra13.universalimageloader.core.download.ImageDownloader;
import com.nostra13.universalimageloader.core.imageaware.ImageAware;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;


/**
 * 作者：machenike on 2016/4/14 13:53
 * 邮箱：
 * <p/>
 * 作用:
 */
public class ImgLoadUtil {



    //ImageLoaderConfiguration 初始化
    public static ImageLoader initImageLoader(ImageLoader imageLoader, Context context) {

        if (imageLoader != null) {
            return imageLoader;
        }



        //File cacheDir = StorageUtils.getOwnCacheDirectory(context.getApplicationContext(), MyPath.getSdPathImg());
        imageLoader = ImageLoader.getInstance();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration
                .Builder(context)
                .memoryCacheExtraOptions(480, 800) //max width, max height，即保存的每个缓存文件的最大长宽
                .threadPoolSize(3)//线程池内加载的数量
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .denyCacheImageMultipleSizesInMemory()
                .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) //你可以通过自己的内存缓存实现
                .memoryCacheSize(2 * 1024 * 1024)
                .discCacheSize(50 * 1024 * 1024)
                .discCacheFileNameGenerator(new Md5FileNameGenerator())//将保存的时候的URI名称用MD5 加密
                .tasksProcessingOrder(QueueProcessingType.LIFO)
                .discCacheFileCount(400) //缓存的文件数量
                //.discCache(new UnlimitedDiscCache(cacheDir))//自定义缓存路径
                .defaultDisplayImageOptions(DisplayImageOptions.createSimple())
                .imageDownloader(new BaseImageDownloader(context, 5 * 1000, 30 * 1000)) // 超时时间
                .writeDebugLogs() // Remove for release app
                .build();//开始构建
        imageLoader.init(config);


        return imageLoader;

    }


    //DisplayImageOptions 初始化
    public static DisplayImageOptions initDisplayImageOptions(DisplayImageOptions options, Context context) {

        if (options != null) {
            return options;
        }


        options = new DisplayImageOptions.Builder()
                //.showImageOnLoading(R.drawable.ic_launcher) //设置图片在下载期间显示的图片
                // .showImageForEmptyUri(R.drawable.ic_launcher)//设置图片Uri为空或是错误的时候显示的图片
                //.showImageOnFail(R.drawable.ic_launcher)  //设置图片加载/解码过程中错误时候显示的图片
                .cacheInMemory(true)///设置下载的图片是否缓存在内存中
                .cacheOnDisc(true)//设置下载的图片是否缓存在SD卡中
                .considerExifParams(true)  //是否考虑JPEG图像EXIF参数（旋转，翻转）
                .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//设置图片以如何的编码方式显示
                .bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型//
                 //.decodingOptions(android.graphics.BitmapFactory.Options decodingOptions)//设置图片的解码配置
                 //.delayBeforeLoading(int delayInMillis)//int delayInMillis为你设置的下载前的延迟时间
                 //.preProcessor(BitmapProcessor preProcessor)//设置图片加入缓存前，对bitmap进行设置
                .resetViewBeforeLoading(true)//设置图片在下载前是否重置，复位
                        //.displayer(new RoundedBitmapDisplayer(20))//是否设置为圆角，弧度为多少
                .displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间
                .build();//构建完成
        return options;

    }


    //Resources 初始化
    public static Resources initResources(Resources resources, Context context) {
        if(resources!=null){
            return resources;
        }
        Resources mResources=resources;
        mResources=context.getResources();

        return  mResources;
    }






    /**
     * 本地图片路径
     *
     * @param path
     * @param imageView
     */
    public static void setImgPath(final String path, final ImageView imageView){

        String imageUrl="";
        if(!path.contains("http")) {
            imageUrl = ImageDownloader.Scheme.FILE.wrap(path);
        }else{
            imageUrl=path;
        }

        Log.e("imageUrl",imageUrl);

        IApplication.getImageLoader().displayImage(imageUrl, imageView, IApplication.getOptions(), new ImageLoadingListener() {
            @Override
            public void onLoadingStarted(String s, View view) {

            }

            @Override
            public void onLoadingFailed(String s, View view, FailReason failReason) {
                ImageView iv = (ImageView) view;
                iv.setBackgroundResource( R.mipmap.img_placeholder);

            }

            @Override
            public void onLoadingComplete(String s, View view, Bitmap bitmap) {
                ImageView iv = (ImageView) view;
                iv.setImageBitmap(bitmap);
            }

            @Override
            public void onLoadingCancelled(String s, View view) {
                ImageView iv = (ImageView) view;
                iv.setBackgroundResource( R.mipmap.img_placeholder);
            }
        });


    }

    //add by Andrew.yin 2017/9/25 begin
    /**
     * 本地图片路径
     *
     * @param path
     * @param imageView
     */
    public static void setImgPath(final String path, final ImageAware imageView){

        String imageUrl="";
        if(!path.contains("http")) {
            imageUrl = ImageDownloader.Scheme.FILE.wrap(path);
        }else{
            imageUrl=path;
        }

        Log.e("imageUrl",imageUrl);

        IApplication.getImageLoader().displayImage(imageUrl, imageView, IApplication.getOptions(), new ImageLoadingListener() {
            @Override
            public void onLoadingStarted(String s, View view) {

            }

            @Override
            public void onLoadingFailed(String s, View view, FailReason failReason) {
                ImageView iv = (ImageView) view;
                iv.setBackgroundResource( R.mipmap.img_placeholder);

            }

            @Override
            public void onLoadingComplete(String s, View view, Bitmap bitmap) {
                ImageView iv = (ImageView) view;
                iv.setImageBitmap(bitmap);
            }

            @Override
            public void onLoadingCancelled(String s, View view) {
                ImageView iv = (ImageView) view;
                iv.setBackgroundResource( R.mipmap.img_placeholder);
            }
        });


    }
    //add by Andrew.yin 2017/9/25 end



    /**
     * 图片比例大小压缩
     *
     * @param srcPath
     *            路径
     * @return
     * @author banxin
     */
    public static Bitmap getBitmap(String srcPath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 根据分辨率设置数值
        float hh = 300f;// 这里设置高度为500f
        float ww = 300f;// 这里设置宽度为500f
        // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;// 设置缩放比例
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        try {
            bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }

        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
    }

    public static Bitmap compressImage(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        } catch (NullPointerException e) {
            e.printStackTrace();
        }

        int options = 100;
        LogUtils.LOGE("length:"+(baos.toByteArray().length/1024) );
        while (baos.toByteArray().length / 1024 > 100&&options>=10) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            options -= 10;// 每次都减少10
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        } catch (OutOfMemoryError e) {

        } catch (Exception e) {
        }
        return bitmap;
    }


    /**
     * 图片比例大小压缩   （带基数的图片压缩）
     *
     * @param srcPath
     *            路径
     * @return
     * @author banxin
     */
    public static Bitmap getBitmap(String srcPath,int minBaseNum) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 根据分辨率设置数值
        float hh = 500f;// 这里设置高度为500f
        float ww = 500f;// 这里设置宽度为500f
        // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;// 设置缩放比例
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        try {
            bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }

        return compressImage(bitmap,minBaseNum);// 压缩好比例大小后再进行质量压缩
    }




    public static Bitmap compressImage(Bitmap image,int minBaseNum) {
        if(minBaseNum<=10){
            minBaseNum=100;
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        } catch (NullPointerException e) {
            e.printStackTrace();
        }

        int options = 100;
        LogUtils.LOGE("初始length:"+(baos.toByteArray().length/1024) );
        while (baos.toByteArray().length / 1024 > minBaseNum&&options>10) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            options -= 10;// 每次都减少10
            //LogUtils.LOGE("初始options:"+options);
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
        }
        LogUtils.LOGE("第一次压缩后length:"+(baos.toByteArray().length/1024) );

        //有必要进行二次压缩
        int optionsTwice = 10;
        while (baos.toByteArray().length / 1024 > minBaseNum&&optionsTwice>1) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            optionsTwice -= 1;// 每次都减少1
            //LogUtils.LOGE("初始optionsTwice:"+optionsTwice);
            image.compress(Bitmap.CompressFormat.JPEG, optionsTwice, baos);// 这里压缩options%，把压缩后的数据存放到baos中
        }
        LogUtils.LOGE("第二次压缩后length:"+(baos.toByteArray().length/1024) );

        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        } catch (OutOfMemoryError e) {

        } catch (Exception e) {
        }
        return bitmap;
    }








    /**
     * 将bitmap转base64
     * @param bitmap
     * @return
     */
    public static String bitmapToBase64(Bitmap bitmap) {

        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }



}
